home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------*/
- /* ANIMDAT 1.1 */
- /* copyright 1992 - TODD SANKEY */
- /* */
- /* The author hereby grants permission for the use and sharing */
- /* of both source code end executable versions of this software */
- /* at no charge. This software is not for sale and no other */
- /* shall charge for it without the expressed consent of the */
- /* author. */
- /* */
- /* The source code can be freely modified, but it must retain */
- /* the original copyright notice, and the author must be */
- /* notified of these changes if the altered code is to be */
- /* distributed. */
- /*--------------------------------------------------------------*/
-
-
- /*--------------------------------------------------------------*/
- /* animdat.c Main file for animdat program. */
- /*--------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <math.h>
- #include "common.h"
-
- /* This definition controls what filenames are used for the generated */
- /* files. If LONG_FILENAMES is not defined, then the generated files */
- /* are named SCENEnnn.DAT where nnn is the number of the scene. If */
- /* LONG_FILENAMES is defined, the generated filenames use the root name */
- /* given on the command line and add _nnn.DAT . */
- /* This option is given because DOS machines have the limit of 8 */
- /* characters in the filename, so LONG_FILENAMES should not be used. */
-
- /* #define LONG_FILENAMES */
-
- #ifdef LONG_FILENAMES
- #define MAX_FNAME_SIZE 100
- #else
- #define MAX_FNAME_SIZE 13
- #endif
-
- #define NAMELEN 20
- #define NUMLEN 20
- #define MAXSCENES 100
- #define VARCHAR '@'
- #define GATECHAR '&'
- #define MAX_LINE_SIZE 256
-
-
- /* Globals used in other modules */
- int numscenes = -1;
- sym_ptr symbol_table = NULL;
- char cur_line[MAX_LINE_SIZE];
- char *cur_file = NULL;
- unsigned int cur_line_num = 0;
-
-
- /* Used within animdat.c */
- static sym_ptr x_symbol = NULL;
- static sym_ptr cur_sc_symbol = NULL;
- static sym_ptr num_sc_symbol = NULL;
- static char *cur_symbol = NULL;
- static int gate_closed = 0;
-
-
- /*--------------------------------------------------------------*/
- /* parse_equation Attaches a binary tree representation */
- /* of a mathematical expression to a symbol*/
- /* given that the scanner module is */
- /* initialized to the first token in the */
- /* expression. */
- /*--------------------------------------------------------------*/
- void parse_equation(sym_ptr new_symbol)
- {
- new_symbol->sym_info = (void *)expression();
- new_symbol->sym_type = SYM_DOUBLE;
- if (token == COMMA) {
- double sign_flag = 1.0;
- get_token();
- if (token == MINUS) {
- sign_flag = (-1.0);
- get_token();
- }
- else if (token == PLUS)
- get_token();
-
- if (token == NUMBER)
- new_symbol->cur_val = sign_flag * literal_value;
- else
- error(SYNTAX_ERROR,cur_line);
- }
-
- }
-
-
-
- /*--------------------------------------------------------------*/
- /* parse_filename Attaches a file pointer to a symbol. */
- /*--------------------------------------------------------------*/
- void parse_filename(sym_ptr new_symbol)
- {
- get_token();
- new_symbol->sym_type = SYM_FILE;
- new_symbol->sym_info = (void *)fopen(word_string,"r");
- if (new_symbol->sym_info == NULL)
- error(FILE_ERROR,word_string);
- get_token();
- }
-
-
- /*--------------------------------------------------------------*/
- /* parse_string Attaches a string pointer to a symbol. */
- /*--------------------------------------------------------------*/
- void parse_string(sym_ptr new_symbol)
- {
- char *quote;
-
- quote=(char *)malloc(strlen(word_string)+1);
- if (quote == NULL)
- error(FAILED_MALLOC,NULL);
-
- strcpy(quote,word_string);
- new_symbol->sym_type = SYM_STRING;
- new_symbol->sym_info = (void *)quote;
- get_token();
- }
-
-
-
-
- /*--------------------------------------------------------------*/
- /* parsevarfile Attempts to parse a file as a sequence */
- /* of lines each containing a symbol name */
- /* and a definition. */
- /*--------------------------------------------------------------*/
- void parsevarfile(FILE *varfile)
- {
- int i;
- sym_ptr new_symbol;
-
- cur_line_num = 0;
- while (!feof(varfile)) {
- /* Read the current line of the file into a buffer */
- if (fgets(cur_line,MAX_LINE_SIZE,varfile) != NULL) {
- cur_line_num++;
- for (i=0; i<MAX_LINE_SIZE && cur_line[i]!='\0'; i++);
- if (cur_line[i]!='\0' || i>=MAX_LINE_SIZE)
- error(LINE_TOO_LONG,cur_line);
-
- init_scanner(cur_line);
-
- if (token == IDENTIFIER) {
- new_symbol = add_symbol(&symbol_table, word_string);
- get_token();
- if (token != EQUAL)
- error(SYNTAX_ERROR,cur_line);
- get_token();
- switch (token) {
- case POUND : parse_filename(new_symbol);break;
- case QUOTE : parse_string(new_symbol); break;
- default : parse_equation(new_symbol);
- }
- }
- else if (token == NUMSCENE) {
- get_token();
- if (token != EQUAL)
- error(SYNTAX_ERROR,cur_line);
- get_token();
- if (token != NUMBER)
- error(SYNTAX_ERROR,cur_line);
- numscenes = (int)literal_value;
- get_token();
- }
- else if (token != END_OF_FILE)
- error(SYNTAX_ERROR,cur_line);
- }
- }
-
- cur_line_num = 0;
- }
-
-
- /*--------------------------------------------------------------*/
- /* add_system_variables Creates the predefined symbols */
- /* but leaves them undefined. */
- /*--------------------------------------------------------------*/
- void add_system_variables()
- {
- sym_ptr symbol;
-
- num_sc_symbol = add_symbol(&symbol_table,"num_scenes");
- x_symbol = add_symbol(&symbol_table,"x");
- cur_sc_symbol = add_symbol(&symbol_table,"cur_scene");
- }
-
-
-
-
- /*--------------------------------------------------------------*/
- /* update_system_variables Defines the system variables. */
- /*--------------------------------------------------------------*/
- void update_system_variables()
- {
- char eq[MAX_LINE_SIZE];
- double xinc;
- sym_ptr symbol;
-
- xinc = 1.0 / ((double)numscenes);
- sprintf(eq,"x + %lf \0",xinc);
- init_scanner(eq);
- x_symbol->sym_info = (void *)expression();
- x_symbol->cur_val = 0.0;
- x_symbol->sym_type = SYM_DOUBLE;
-
- sprintf(eq,"cur_scene + 1 \0");
- init_scanner(eq);
- cur_sc_symbol->sym_info = (void *)expression();
- cur_sc_symbol->cur_val = 0.0;
- cur_sc_symbol->sym_type = SYM_DOUBLE;
-
- sprintf(eq,"%d \0",numscenes);
- init_scanner(eq);
- num_sc_symbol->sym_info = (void *)expression();
- num_sc_symbol->cur_val = (double)numscenes;
- num_sc_symbol->sym_type = SYM_DOUBLE;
- }
-
-
-
-
-
- /*--------------------------------------------------------------*/
- /* check_btree Scans a binary tree representation */
- /* of a mathematical expression checking */
- /* for undefined symbols. */
- /*--------------------------------------------------------------*/
- void check_btree(btree_node_ptr bnode)
- {
- if (bnode->node_type == NAMEDVAR) {
- if (search_symtab(symbol_table,bnode->node_data.name) == NULL) {
- sprintf(cur_line,"%s in definition of %s",bnode->node_data.name,cur_symbol);
- error(UNDEFINED_SYMBOL,cur_line);
- }
- }
- }
-
-
-
-
- /*--------------------------------------------------------------*/
- /* check_symbol Verifies the definition of a symbol. */
- /*--------------------------------------------------------------*/
- void check_symbol(sym_ptr symbol)
- {
- cur_symbol = symbol->name;
- if (symbol->sym_type == SYM_DOUBLE)
- traverse_btree((btree_node_ptr)(symbol->sym_info),check_btree);
- }
-
-
-
-
- /*--------------------------------------------------------------*/
- /* reset_flags Clears the flag in a symbol which */
- /* indicates that the symbol value has */
- /* already been evaluated for this scene. */
- /*--------------------------------------------------------------*/
- void reset_flags(sym_ptr symbol)
- {
- symbol->update_flag = 0;
- }
-
-
-
-
- void main(int argc,char **argv)
- {
- int curscene,inchar,i;
- char varname[MAX_LINE_SIZE];
- FILE *datfile,*curscenefile,*varfile;
- sym_ptr symbol;
- char dat_name[MAX_FNAME_SIZE];
- char var_name[MAX_FNAME_SIZE];
- char scene_name[MAX_FNAME_SIZE];
-
- if (argc != 2) {
- printf("ANIMDAT <root file>\n");
- printf(" where rootfile.dat is the template file\n");
- printf(" and rootfile.var is the variable definition file\n");
- exit(1);
- }
-
- strcpy(dat_name, argv[1]);
- strcat(dat_name,".dat");
- datfile=fopen(dat_name,"r");
- if (datfile == NULL) {
- printf(" Could not open datfile: %s\n", dat_name);
- exit(1);
- }
-
- strcpy(var_name, argv[1]);
- strcat(var_name, ".var");
- varfile=fopen(var_name,"r");
- if (varfile == NULL) {
- printf(" Could not open varfile: %s\n", var_name);
- exit(1);
- }
-
- cur_file = var_name;
- add_system_variables();
- parsevarfile(varfile);
- fclose(varfile);
- update_system_variables();
- traverse_symtab(symbol_table,check_symbol);
-
- if (numscenes<=0)
- error(NO_NUMSCENE,NULL);
-
- cur_file = dat_name;
- cur_line_num = 1;
-
- #ifndef LONG_FILENAMES
- strcpy(scene_name,"scene000.dat");
- #endif
-
- for (curscene=1;curscene<=numscenes;curscene++) {
-
- #ifdef LONG_FILENAMES
- sprintf(scene_name,"%s_%d.dat",argv[1],curscene);
- #else
- sprintf(scene_name,"scene%03d.dat",curscene);
- #endif
-
- curscenefile=fopen(scene_name,"w");
-
- if (curscenefile==NULL) {
- printf("Could not open file %s\n",scene_name);
- exit(1);
- }
-
- rewind(datfile);
- traverse_symtab(symbol_table,reset_flags);
-
- gate_closed = 0;
- while (!feof(datfile)) {
- inchar=fgetc(datfile);
-
- switch (inchar) {
- case VARCHAR :
- if (!gate_closed) {
- i = 0;
- do {
- inchar=fgetc(datfile);
- if (inchar != VARCHAR) {
- varname[i] = inchar;
- i++;
- }
- } while ( i < (MAX_LINE_SIZE - 1) && inchar !=VARCHAR);
-
- varname[i] = '\0';
- if (inchar!=VARCHAR)
- fprintf(curscenefile,"%c%s",VARCHAR,varname);
- else
- print_symbol(curscenefile,varname);
- }
- break;
-
- case GATECHAR :
- inchar = fgetc(datfile);
- if (isalpha(inchar)) { /* Assume start of gate */
- i = 0;
- do {
- varname[i] = inchar;
- i++;
- inchar = fgetc(datfile);
- } while (i < (MAX_LINE_SIZE - 1) && (isalnum(inchar) || inchar=='_') );
- varname[i] = '\0';
- if ( (eval_symbol(varname) <= 0.0) || gate_closed)
- gate_closed++;
- }
-
- else if (gate_closed)
- gate_closed--; /* End of gate */
- break;
-
- case EOF :
- break;
-
- default:
- if (!gate_closed) {
- fputc(inchar,curscenefile);
- if (inchar == '\n')
- cur_line_num++;
- }
-
-
-
- }
- }
-
- fclose(curscenefile);
- }
-
- }
-